home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HyperLib 1997 Winter - Disc 1
/
HYPERLIB-1997-Winter-CD1.ISO.7z
/
HYPERLIB-1997-Winter-CD1.ISO
/
オンラインウェア
/
BUS
/
BibTeX 1.06 FAT.sit
/
BibTeX ƒ
/
Source code
/
bibext.cc
next >
Wrap
C/C++ Source or Header
|
1996-05-17
|
9KB
|
390 lines
/*
* Auxilliary routines for BibTeX in C.
*
* Tim Morgan 2/15/88
* Eduardo Krell 4/21/88
* Vince Darley 2/96
*/
#include <stdlib.h>
#include <string.h>
#include "MoreFilesExtras.h"
#define filenamesize 1024
#include "bibutils.h"
#include "BibTeX.h"
#include "file-io.h"
#include "CBibTeXApp.h"
#include "bibext.h"
#define getc(a) GetBibtexCharacter(a)
#define ungetc(a,b) UnGetC(a,b)
#define feof(a) FEof(a)
static void packrealnameoffile(char ** cpp );
static unsigned long GetDirIDFromFSSpec(FSSpecPtr pFSS);
static FSSpec getAppSpec(void);
/*
* Declarations for file search
*/
FSSpec Folders[3];
FInfo AuxFileInfo;
extern char realnameoffile[];
extern char xord[], *buffer, nameoffile[]; /* change buffer for dyn alloc, jws */
static char input_path[filenamesize];
/*
This important function will open a file, finding it in any of
the directories specified if required, if the file is for creating
it gives it the correct creator (same as the .aux).
To Do:
Although I've changed a lot here, it would be sensible to do
away with the odd scheme of find and open file, then close it
and re-open.
Vince Feb'96
Side effects: allocates a FileDescPtr which must be freed by
the caller (my CloseFile frees this automatically).
*/
#ifdef STDC
BIBFILE *openf(char * name ,char * mode )
#else
BIBFILE *openf(name ,mode )
char *name, *mode;
#endif
{
/*
* Variables for directory search ... jdl
*/
short refnum;
int cFolder, nPath;
OSErr ferr;
char **PathHandle, *PathPtr;
char expand_name[100];
Str63 temp;
{ /* ###### LSC doesn't like ./ (jws) */
if ( name[0] == '.' && name[1] == '/') name += 2;
}
/*
* Directory search stuff ... jdl
*/
PathHandle = (char **) GetResource('STR#', 130); /* Path resource */
if (!PathHandle) {
FatalOSErr("Path Resource not present!!!¥n",0);
}
HLock(PathHandle);
PathPtr = *PathHandle;
// this no longer works on PPC:
//nPath = *((int *) PathPtr);
//PathPtr += sizeof(int);
// must use this:
nPath = (int) PathPtr[1]; // # of path elements
PathPtr += 2;
FSSpec newSpec;
// We grab the entire path resource and scan through it ourselves.
while (nPath-- > 0) {
PtoCstr((unsigned char*) PathPtr);
cFolder = *PathPtr - '0'; // which folder:0 =current,1 = tex inputs,2=path given
if (cFolder < 0 || cFolder > 2) {
FatalOSErr("Invalid path decription %s¥n", PathPtr,0);
}
strcpy(expand_name, &PathPtr[1]);
strcat(expand_name, name);
CtoPstr(expand_name);
CtoPstr(PathPtr);
ferr = FSMakeFSSpec(Folders[cFolder].vRefNum, Folders[cFolder].parID,
(unsigned char*) expand_name, &newSpec);
if (!ferr)
break;
PathPtr = PathPtr + *PathPtr + 1; /* point at the next one */
}
HUnlock(PathHandle);
// give up the memory
ReleaseResource(PathHandle);
if (mode[0] == 'r') {
if(ferr) {
// file should exist, we can't find it
FatalOSErr("File %s not found¥n",name,0);
//perror(name);
} else {
ferr = FSpOpenDF(&newSpec, fsRdPerm, &refnum);
if (ferr == opWrErr) {
// already open for writing, probably an error
FSClose(refnum);
ferr = FSpOpenDF(&newSpec, fsRdPerm, &refnum);
ferr = 0;
}
}
} else {
if(ferr) {
// new file, put into same folder as aux file
strcpy(expand_name, name);
CtoPstr(expand_name);
cFolder = 0;
ferr = FSMakeFSSpec(Folders[cFolder].vRefNum, Folders[cFolder].parID,
(unsigned char*) expand_name, &newSpec);
if (ferr == fnfErr) {
ferr = FSpCreate(&newSpec,AuxFileInfo.fdCreator, 'TEXT',0);
}
if (ferr) {
FatalOSErr("Cound not create file %s error = %d¥n", name, ferr);
}
}
// file now exists, so overwrite
ferr = FSpOpenDF(&newSpec, fsWrPerm, &refnum);
if (ferr == opWrErr) {
// already open for writing, probably an error
FSClose(refnum);
ferr = FSpOpenDF(&newSpec, fsWrPerm, &refnum);
ferr = 0;
}
if (ferr) {
FatalOSErr("Couldn't open file %s for writing, error = %d¥n", name, ferr);
}
}
/* We can probably do away with this opening twice nonsense */
/* (it's a relic of the old version) */
FSClose(refnum); /* Yes we open the file twice.... */
PtoCstr((unsigned char*) expand_name);
temp[0] = sprintf((char *) temp + 1, "%s", expand_name);
FileDesc& gTempDesc = *(new FileDesc);
gTempDesc.refNum = 0;
OSErr err = ::FSMakeFSSpec(Folders[cFolder].vRefNum, Folders[cFolder].parID, temp,
&gTempDesc.spec);
if (err == fnfErr)
FatalOSErr("Error locating log file %s: %s.",
(char *) temp + 1, err);
gTempDesc.spec.name[StrLength(gTempDesc.spec.name) + 1] = '¥0';
if ( mode[0] == 'r' ) {
OpenInputFile(&gTempDesc);
FSeek(&gTempDesc,0,0);
} else if ( mode[0] == 'w' ) {
OpenOutputFile(&gTempDesc);
} else {
FatalOSErr("Called open file with unknown mode; weird internal error",0);
}
if (!&gTempDesc) {
FatalOSErr("Problem opening file %s¥n", name,0);
}
return(&gTempDesc);
}
#ifdef STDC
void lineread(BIBFILE * f ,int size )
#else
void lineread( f , size )
BIBFILE * f;
int size;
#endif
{
extern long last;
int in;
last = 0;
while (last < size && (in = getc(f)) != EOF && in != '¥r' ) {
#ifdef NONASCII
buffer[last++] = xord[in];
#else
buffer[last++] = in;
#endif
}
while (in != EOF && in != '¥r' ) // Skip past eoln if buffer full
in = getc(f);
}
void setpaths()
{
char *p;
// it's actually important the input_path gets a '.' put in it
if ((int)(p = getenv("TEXINPUTS")))
(void) strcpy(input_path, p);
else
(void) strcpy(input_path, TEXINPUTS);
extern FileDesc gAuxDesc;
Folders[0] = gAuxDesc.spec;
// make this the default path in case we want to open it again
SetVol(0L, Folders[0].parID);
Folders[1] = getAppSpec();
// folders [2] requires a full path name to be specified
Folders[2].vRefNum = 0;
Folders[2].parID = 0;
}
#ifdef STDC
int testaccess(int wam ,int filepath )
#else
int testaccess( wam , filepath )
int wam, filepath;
#endif
{
char *path = NULL;
register int ok;
if (filepath == 1)
path = input_path;
if (nameoffile[0] == '/')
path = NULL;
do {
packrealnameoffile(&path);
if (wam == 4)
if (access(realnameoffile, 4) == 0) ok = TRUE;
else ok = FALSE;
else {
/* fake this ... jdl
f = creat(realnameoffile, 0666);
if (f >= 0) ok = TRUE;
else ok = FALSE;
if (ok)
(void) close(f);
*/
ok = TRUE;
/* done ... jdl */
}
}
while (!ok && path != NULL);
/*
if (ok) {
for (p=realnameoffile; *p; p++);
while (p < &(realnameoffile[filenamesize]))
*p++ = ' ';
}
*/
return(ok);
}
#ifdef STDC
static void packrealnameoffile(char ** cpp )
#else
static void packrealnameoffile( cpp )
char ** cpp;
#endif
{
register char *p, *realname;
realname = realnameoffile;
if ((int)(p = *cpp)) {
while ((*p != ':') && *p) {
*realname++ = *p++;
if (realname == &(realnameoffile[filenamesize-1]))
break;
}
if (*p == '¥0') *cpp = NULL;
else *cpp = p+1;
*realname++ = '/';
}
p = nameoffile;
while (*p != ' ') {
if (realname >= &(realnameoffile[filenamesize-1])) {
FPrintFStdErr( "! Full file name is too long¥n");
break;
}
*realname++ = *p++;
}
*realname = '¥0';
}
extern void main_body(void);
#undef __profile__
#ifdef __profile__
#include <profiler.h>
#endif
void vince_main(void){
extern FileDescPtr myBufferedFile;
myBufferedFile = 0;
setpaths();
main_body();
#ifdef __profile__
ProfilerDump("¥pbibprof");
ProfilerTerm();
#endif
}
unsigned long GetDirIDFromFSSpec(FSSpecPtr pFSS)
{
CInfoPBRec myCPB; /* for the PBGetCatInfo call */
OSErr err;
FSSpec localFSS;
// copy the FSS, so we don't change it:
BlockMove(pFSS, &localFSS, sizeof(FSSpec));
myCPB.hFileInfo.ioNamePtr = localFSS.name;
myCPB.hFileInfo.ioVRefNum = localFSS.vRefNum;
myCPB.hFileInfo.ioDirID = localFSS.parID;
myCPB.hFileInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync(&myCPB);
if ((myCPB.hFileInfo.ioFlAttrib & ioDirMask) != 0)
return myCPB.hFileInfo.ioDirID; // we have a directory, return the dirID
else
return localFSS.parID; // for a file, return the parent ID.
}
/* no exit = LocalExit in here */
#undef exit
#ifdef STDC
void LocalExit(int i)
#else
void LocalExit(i)
int i;
#endif
{
//Click_On( i!=0); /* only click for errors */
exit(i);
}
FSSpec getAppSpec(void) {
OSErr myErr ;
ProcessInfoRec myProInfo ;
ProcessSerialNumber myPSN ;
FSSpec FS ;
myPSN.highLongOfPSN = 0;
myPSN.lowLongOfPSN = kCurrentProcess;
myProInfo.processInfoLength = sizeof(ProcessInfoRec);
myProInfo.processName = nil;
myProInfo.processAppSpec = &FS;
myErr = GetProcessInformation(&myPSN, &myProInfo);
return FS;
}